import numbers


class Field(object):
    pass


class IntField(Field):
    """docstring for IntField."""


    def __init__(self, db_column, min_value=None, max_value=None):
        self._value = None
        self.db_column = db_column
        self.min_value = min_value
        self.max_value = max_value
        if min_value is None:
            raise ValueError('the min_value is None!')
        if max_value is None:
            raise ValueError('the max_value is None!')
        if not isinstance(min_value, int): raise ValueError('the min_value must is int!')
        if not isinstance(max_value, int): raise ValueError('this max_value is int')
        if min_value < 0:
            raise ValueError('the min_value is must >0')
        if max_value < 0:
            raise ValueError('the max_value is must >0')
        if min_value > max_value:
            raise ValueError('the min_value must < max_value')

    def __get__(self, instance, owner):
        return self._value

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise ValueError("int value needs")
        if value < 0:
            raise ValueError("positive vaule needs")
        self._value = value


class CharField(Field):
    """docstring for IntField."""

    def __init__(self, db_column, max_length=None):
        self._value = None
        self.db_column = db_column
        if max_length is None:
            raise ValueError('the max_value is None!')
        if not isinstance(max_length, int):
            raise ValueError('this max_value is int')
        if max_length < 0:
            raise ValueError('the max_value is must >0')

    def __get__(self, instance, owner):
        return self._value

    def __set__(self, instance, value):
        if not isinstance(value, str):
            raise ValueError("str value needs")
        self._value = value


class ModelMetaClass(type):
    """docstring for IntField."""

    def __new__(cls, name, bases, attrs, *args, **kwargs):
        if name == "BaseModel": return super().__new__(cls, name, bases, attrs, *args, **kwargs)
        fields = {}
        for k, v in attrs.items():
            if isinstance(v, Field): fields[k] = v
        attrs_meta = attrs.get('Meta', None)
        _meta = {}
        db_table = name.lower()
        if attrs_meta is not None:
            table = getattr(attrs_meta, "db_table", None)
            if table is not None: db_table = table
        _meta["db_table"] = db_table
        attrs["_meta"] = _meta
        attrs["fields"] = fields
        del attrs['Meta']
        return super().__new__(cls, name, bases, attrs, *args, **kwargs)


class BaseModel(metaclass=ModelMetaClass):
    def __init__(self, *args, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)
        return super().__init__()


class User(BaseModel):
    name = CharField(db_column="", max_length=10)
    age = IntField(db_column="", min_value=0, max_value=100)

    def save(self):
        pass

    class Meta:
        db_table = "user"


if __name__ == '__main__':
    user = User(name="zhangsan", age=33)
    user.save()
